{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "# Network Representation, Queries, and Manipulation\n",
    "\n",
    "To understand how to query and manipulate the network, we'll first cover the various forms of network representation. Specifically, OpenPNM uses an adjacency matrix to represent topology, but occasionally invokes the incidence matrix since this makes it easier for some queries. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 212,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import openpnm as op\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "op.visualization.set_mpl_style()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The Adjacency Matrix\n",
    "\n",
    "The basic adjacency matrix is an Np-by-Np array of 1's and 0's, where a 1 in location `[i, j]` indicates that pores `i` and `j` are connected. Consider a simple network:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 213,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn = op.network.Cubic(shape=[3, 2, 1], connectivity=26)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It's adjacency matrix can be generated as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 214,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 1 1 1 0 0]\n",
      " [1 0 1 1 0 0]\n",
      " [1 1 0 1 1 1]\n",
      " [1 1 1 0 1 1]\n",
      " [0 0 1 1 0 1]\n",
      " [0 0 1 1 1 0]]\n"
     ]
    }
   ],
   "source": [
    "am = pn.create_adjacency_matrix().todense()\n",
    "print(am)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The adjacency matrix can also be plotted as an image for a helpful visualization:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 215,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAASsAAAEvCAYAAAAdNeeiAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8/fFQqAAAACXBIWXMAAAsTAAALEwEAmpwYAAALgUlEQVR4nO3d34udB4HG8efZ2bSxsYtQs9I0ZeuFCiJuKkP2IrCwXddELbqXLeiVMDcrVFYQvfQfEG/2JmhxF12LUAvSdR3D2lIK2nZSp93G1FJKF8MI6VbExrKtjc9e5CiTOJPzTpn3vHk63w8MOSfncOZhSL7znh+c4yQCgGvdn009AACGIFYAKhArABWIFYAKxApABWIFoMKfj3Gj1/n67NeBMW56NO/94KtTT8A17Lmnb5h6wp7wf/qtXs9r3uqyUWK1Xwf0N/77MW56NKur61NPwDXs+KEjU0/YEx7Lf217GXcDAVQgVgAqECsAFYgVgArECkAFYgWgArECUIFYAahArABUIFYAKhArABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVBgUK9snbP/c9vO2vzj2KAC40txY2V6S9C+SPirp/ZLutv3+sYcBwGZDjqyOSno+yQtJXpd0n6RPjjsLAC43JFa3SPrFpvPnZn8HAAsz5NNttvpYnPzJlewVSSuStF98bBGA3TXkyOqcpFs3nT8saePKKyU5mWQ5yfI+Xb9b+wBA0rBYPSHpPbbfbfs6SXdJ+t64swDgcnPvBiZ5w/ZnJa1KWpJ0b5Izoy8DgE0GfSJzku9L+v7IWwBgW7yCHUAFYgWgArECUIFYAahArABUIFYAKhArABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVCBWACoQKwAViBWACsQKQIVB7xS6U+/94KtaXV0f46ZHc/zQkaknvCmrG+tTTwAWgiMrABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVCBWACoQKwAViBWACsQKQAViBaACsQJQgVgBqECsAFQgVgAqECsAFYgVgApzY2X7XtvnbT+ziEEAsJUhR1bfkHRi5B0AcFVzY5XkEUm/WsAWANgWj1kBqLBrsbK9YnvN9tpLL1/crZsFAEm7GKskJ5MsJ1k+eNPSbt0sAEjibiCAEkNeuvBtST+W9D7b52x/ZvxZAHC5uR8fn+TuRQwBgKvhbiCACsQKQAViBaACsQJQgVgBqECsAFQgVgAqECsAFYgVgArECkAFYgWgArECUIFYAahArABUIFYAKhArABWIFYAKxApAhblva7xXrG6sTz3hTTl+6MjUE3as8WfduLnR0eOvbnsZR1YAKhArABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVCBWACoQKwAViBWACsQKQAViBaACsQJQgVgBqECsAFQgVgAqzI2V7VttP2T7rO0ztu9ZxDAA2GzI2xq/IenzSZ60faOk07ZPJfnZyNsA4I/mHlkl+WWSJ2enX5F0VtItYw8DgM129JiV7dsk3S7psVHWAMA2BsfK9tsl3S/pc0l+s8XlK7bXbK+99PLF3dwIAMNiZXufLoXqW0m+u9V1kpxMspxk+eBNS7u5EQAGPRtoSV+XdDbJV8afBAB/asiR1TFJn5Z0h+312dfHRt4FAJeZ+9KFJI9K8gK2AMC2eAU7gArECkAFYgWgArECUIFYAahArABUIFYAKhArABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVCBWACoQKwAViBWACsQKQIUhn8iMa9jqxvrUE3bs+KEjU0/Yscaf81sNR1YAKhArABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVCBWACoQKwAViBWACsQKQAViBaACsQJQgVgBqECsAFQgVgAqECsAFebGyvZ+24/bfsr2GdtfXsQwANhsyHuwvybpjiQXbO+T9Kjt/0zyk5G3AcAfzY1Vkki6MDu7b/aVMUcBwJUGPWZle8n2uqTzkk4leWzUVQBwhUGxSnIxyRFJhyUdtf2BK69je8X2mu21l16+uMszAex1O3o2MMmvJT0s6cQWl51Mspxk+eBNS7uzDgBmhjwbeND2O2an3ybpw5KeHXkXAFxmyLOBN0v6V9tLuhS37yR5cNxZAHC5Ic8GPi3p9gVsAYBt8Qp2ABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVCBWACoQKwAViBWACsQKQAViBaACsQJQgVgBqECsAFQgVgAqECsAFYa8rfGOPff0DTp+6MgYN40rrG6sTz1hxxo3t/57bvxZb4cjKwAViBWACsQKQAViBaACsQJQgVgBqECsAFQgVgAqECsAFYgVgArECkAFYgWgArECUIFYAahArABUIFYAKhArABWIFYAKg2Nle8n2T20/OOYgANjKTo6s7pF0dqwhAHA1g2Jl+7Ckj0v62rhzAGBrQ4+svirpC5J+P94UANje3FjZvlPS+SSn51xvxfaa7bXf6bVdGwgA0rAjq2OSPmH7RUn3SbrD9jevvFKSk0mWkyzv0/W7PBPAXjc3Vkm+lORwktsk3SXpR0k+NfoyANiE11kBqLCjj49P8rCkh0dZAgBXwZEVgArECkAFYgWgArECUIFYAahArABUIFYAKhArABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVCBWACoQKwAViBWACsQKQIUdva0xsFetbqxPPeFNOX7oyNQTduS5vLztZRxZAahArABUIFYAKhArABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVCBWACoQKwAViBWACsQKQAViBaACsQJQgVgBqDDonUJtvyjpFUkXJb2RZHnMUQBwpZ28rfHfJfnf0ZYAwFVwNxBAhaGxiqQf2j5te2XMQQCwlaF3A48l2bD9l5JO2X42ySObrzCL2Iok7dcNuzwTwF436Mgqycbsz/OSHpB0dIvrnEyynGR5n67f3ZUA9ry5sbJ9wPaNfzgt6SOSnhl7GABsNuRu4LskPWD7D9f/9yQ/GHUVAFxhbqySvCDprxewBQC2xUsXAFQgVgAqECsAFYgVgArECkAFYgWgArECUIFYAahArABUIFYAKhArABWIFYAKxApABWIFoAKxAlCBWAGoQKwAVCBWACo4ye7fqP2SpP/Z9RuW3imp8VOhG3ezeTEaN0vj7f6rJAe3umCUWI3F9lqS5al37FTjbjYvRuNmaZrd3A0EUIFYAajQFquTUw94kxp3s3kxGjdLE+yueswKwN7VdmQFYI+qiZXtE7Z/bvt521+ces88tu+1fd72M1NvGcr2rbYfsn3W9hnb90y9aQjb+20/bvup2e4vT71pKNtLtn9q+8Gptwxh+0Xb/2173fbaQr93w91A20uSnpP0D5LOSXpC0t1JfjbpsKuw/beSLkj6tyQfmHrPELZvlnRzkidt3yjptKR/vJZ/zpJk25IOJLlge5+kRyXdk+QnE0+by/Y/S1qW9BdJ7px6zzy2X5S0nGThrw1rObI6Kun5JC8keV3SfZI+OfGmq0ryiKRfTb1jJ5L8MsmTs9OvSDor6ZZpV82XSy7Mzu6bfV3zv4VtH5b0cUlfm3pLg5ZY3SLpF5vOn1PBf6Jmtm+TdLukxyaeMsjs7tS6pPOSTiVp2P1VSV+Q9PuJd+xEJP3Q9mnbK4v8xi2x8hZ/d83/5mxl++2S7pf0uSS/mXrPEEkuJjki6bCko7av6bvetu+UdD7J6am37NCxJB+S9FFJ/zR7uGMhWmJ1TtKtm84flrQx0Za3tNljPvdL+laS7069Z6eS/FrSw5JOTLtkrmOSPjF7DOg+SXfY/ua0k+ZLsjH787ykB3TpIZqFaInVE5LeY/vdtq+TdJek70286S1n9kD11yWdTfKVqfcMZfug7XfMTr9N0oclPTvpqDmSfCnJ4SS36dK/5x8l+dTEs67K9oHZEy+yfUDSRyQt7NnuilgleUPSZyWt6tKDvt9JcmbaVVdn+9uSfizpfbbP2f7M1JsGOCbp07r0W3599vWxqUcNcLOkh2w/rUu/2E4lqXgpQJl3SXrU9lOSHpf0H0l+sKhvXvHSBQCoOLICAGIFoAKxAlCBWAGoQKwAVCBWACoQKwAViBWACv8PSXttWwgtLKAAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 360x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 1, figsize=[5, 5])\n",
    "ax.imshow(am);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are a few notable features to point out:\n",
    "* The matrix is symmetrical, since pore `i` connects to `j` and `j` connects to `i`\n",
    "* Each row contains only a few entries since a given pore only has a few neighbors.  It may not be obvious above since the network is small, but as the network grows to millions of pores, each pore only has on the order of 10 neighbors.\n",
    "* You can find which pores are neighbors of pore `i` by finding the locations on non-zeros in row `i` of the adjacency matrix\n",
    "* No entries are found in the diagonal since this would indicate that a pore connects with itself which is not physically meaningful.\n",
    "* Since each pair of pores is connected by a single throat then each nonzero entry in the matrix corresponds to a throat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### COO Sparse Format\n",
    "\n",
    "The fact that each row contains very few entries suggests that the matrix should be represented with a sparse format. This is especially important when we start to consider networks with millions of pores which would require a very large amount of memory to store an array of mostly 0's. The most intuitive sparse storage scheme is the COOrdinate format. Since the matrix is symmetrical, we only need to store the upper (or lower) triangular part.  This gives:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 216,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  (0, 1)\t1\n",
      "  (2, 3)\t1\n",
      "  (4, 5)\t1\n",
      "  (0, 2)\t1\n",
      "  (1, 3)\t1\n",
      "  (2, 4)\t1\n",
      "  (3, 5)\t1\n",
      "  (0, 3)\t1\n",
      "  (2, 5)\t1\n",
      "  (1, 2)\t1\n",
      "  (3, 4)\t1\n"
     ]
    }
   ],
   "source": [
    "am = pn.create_adjacency_matrix(triu=True)\n",
    "print(am)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first two columns are the pore indices of the connected pores.  The third column is the value stored in the matrix, which in the standard adjacency matrix is 1.  However, it is convenient to note throat indices are *defined* by this list, meaning that pores 0 and 1 are connected by throat 0, pores 2 and 3 are connected by throat 1, and so on. Putting the throat indices into the adjacency matrix gives:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'pn' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_21532/1750892718.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mam\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcreate_adjacency_matrix\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mweights\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mpn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mTs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtriu\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      2\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mam\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'pn' is not defined"
     ]
    }
   ],
   "source": [
    "am = pn.create_adjacency_matrix(weights=pn.Ts, triu=True)\n",
    "print(am)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```{warning}\n",
    "  Python's 0-indexing become problematic here since the first throat is labelled 0, which technically is a 'non-entry' in a sparse matrix. Scipy's sparse storage schemes are able to handle this because they only look at which locations are defined as non-zeros (i.e., the left column), but it's worth keeping in mind when working with these sparse representations since it can lead to problems.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "### Other Sparse Formats\n",
    "\n",
    "The COO format described above is the basis for OpenPNMs data storage; however, it is not very suitable for performing \"queries\" such as which pores are neighbors to pore `i`?  In fact, the only query that can be performed directly with the COO format is to find which pores are connected by throat `k`, which is just the `(i, j)` values on row `k`. Luckily, there are several other sparse formats we can use. The \"List of Lists\" format is quite useful."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can look for the locations of nonzeros, which tells us which pores are connected to pore `i`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 218,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3]\n",
      "[0, 2, 3]\n",
      "[0, 1, 3, 4, 5]\n",
      "[0, 1, 2, 4, 5]\n",
      "[2, 3, 5]\n",
      "[2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "am = pn.create_adjacency_matrix(weights=pn.Ts, fmt='lil', triu=False)\n",
    "for locations_of_nonzeros in am.rows:\n",
    "    print(locations_of_nonzeros)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that we are looking at the symmetrical version of this array since we want to see all connections for each pore. \n",
    "\n",
    "Or we can look at the values of the nonzeros, which tells us which throats are connected to pore `i`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 219,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 3, 7]\n",
      "[0, 9, 4]\n",
      "[3, 9, 1, 5, 8]\n",
      "[7, 4, 1, 10, 6]\n",
      "[5, 10, 2]\n",
      "[8, 6, 2]\n"
     ]
    }
   ],
   "source": [
    "for values_of_nonzeros in am.data:\n",
    "    print(values_of_nonzeros)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another query we might wish to do is determine which throat connects which pair of pores. The \"Dictionary of Keys\" format is useful for this.  It is basically the COO format, but the `(i, j)` values are used as the dictionary keys.  This is helpful since dictionary lookups are actually quite fast thanks to some sophisticated data structures used by python. Consider the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 220,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pores (0, 1): 0\n"
     ]
    }
   ],
   "source": [
    "am = pn.create_adjacency_matrix(weights=pn.Ts, fmt='dok', triu=False)\n",
    "print('pores (0, 1):', am[(0, 1)])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One *gotcha* with this approach is that if you request the throat that connects two pores which are not connected, then it returns 0, which makes sense if the adjacency matrix is filled with 1's and 0's, but when throat indices are used as the weights, then 0 is a valid throat number, so receiving a 0 back from a query does not indicate lack of connection. This can be remedied by adding 1 to the throat indices when generating the adjacency matrix, then subtracting 1 again to return the actual throat number: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 221,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pores (5, 5): -1\n"
     ]
    }
   ],
   "source": [
    "am = pn.create_adjacency_matrix(weights=pn.Ts+1, fmt='dok', triu=False)\n",
    "print('pores (5, 5):', am[(5, 5)]-1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The Incidence Matrix\n",
    "\n",
    "The incidence matrix is a slight variation on the adjacency matrix, but is it tells us which pore is connected to which throat.  In other words, it is an Np-by-Nt array, with a nonzero value at location `[i, k]` indicating that pore `i` is connected to throat `k`.  It looks like:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 222,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 0 0 1 0 0 0 1 0 0 0]\n",
      " [1 0 0 0 1 0 0 0 0 1 0]\n",
      " [0 1 0 1 0 1 0 0 1 1 0]\n",
      " [0 1 0 0 1 0 1 1 0 0 1]\n",
      " [0 0 1 0 0 1 0 0 0 0 1]\n",
      " [0 0 1 0 0 0 1 0 1 0 0]]\n"
     ]
    }
   ],
   "source": [
    "im = pn.create_incidence_matrix().todense()\n",
    "print(im)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see that finding the locations of nonzeros values in row `i` tells us which throats are connected to pore `i`. This is the same information we can get from the COO format of the adjacency matrix. The incidence matrix is thus not really helpful."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Using OpenPNM Methods Query Methods\n",
    "\n",
    "The above introduction was meant to provide some background on how neighbor queries are performed \"behind the scenes\", but it is not very convenient to use those approaches directly. Instead, you can use the methods included in OpenPNM, specifically, the methods attached to the *Network* class:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 223,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "pn = op.network.Cubic(shape=[4, 4, 1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's start by finding all pores on the 'left' and 'bottom'.  These labels are predefined on `Cubic` networks, and we can use the `pores` method to find all pores with these labels:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 224,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3]\n",
      "[ 3  7 11 15]\n"
     ]
    }
   ],
   "source": [
    "P_left = pn.pores('left')\n",
    "P_bottom = pn.pores('back')\n",
    "print(P_left)\n",
    "print(P_bottom)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find Neighoring Pores\n",
    "We now have two sets of pores that actually overlap each other, as illustrated below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 225,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, pn.Ps, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_left, c='red', marker='*',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_bottom, c='blue', marker='.',\n",
    "                                  markersize=50, ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`mode='or'` finds all pores with one or more connections to the input pores\n",
    "\n",
    "Given a set of pores, find the pores that are neighbors to one or more of the inputs.  This is called **OR** since it gives the neighbors of either the bottom pores *or* the left pores, *or* both.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 226,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0  1  2  3  7 11 15]\n",
      "[ 4  5  6 10 14]\n"
     ]
    }
   ],
   "source": [
    "Ps = pn.pores(['left', 'back'])\n",
    "print(Ps)\n",
    "Ps = pn.find_neighbor_pores(pores=Ps, mode='or')\n",
    "print(Ps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 227,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, pn.Ps, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_left, c='red',\n",
    "                                  markersize=50, marker='*', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_bottom, c='blue',\n",
    "                                  markersize=50, marker='.', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, Ps, c='green',\n",
    "                                  markersize=50, marker='s', ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`mode='xor' finds all pores with exactly one connection to the input pores\n",
    "\n",
    "Given a set of pores find the pores that are neighbors of one and only one of the input pores.  This is called **XOR**, or 'exclusive_or' because it finds the pores that are neigbhors to the 'bottom' *or* the 'left', but *not* both. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 228,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0  1  2  3  7 11 15]\n",
      "[ 4  5 10 14]\n"
     ]
    }
   ],
   "source": [
    "Ps = pn.pores(['left', 'back'])\n",
    "print(Ps)\n",
    "Ps = pn.find_neighbor_pores(pores=Ps, mode='xor')\n",
    "print(Ps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 229,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, pn.Ps, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_left, c='red',\n",
    "                                  markersize=50, marker='*', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_bottom, c='blue',\n",
    "                                  markersize=50, marker='.', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, Ps, c='green',\n",
    "                                  markersize=50, marker='s', ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`mode='xnor'` finds all the pores with 2 or more connections to the input pores\n",
    "\n",
    "This finds pores that are common to both 'left' and 'bottom' pores.  It is called **XNOR** since it is the opposite of **XOR** , indicated by the *N for not* .   Note that **XNOR** and **NXOR** are interchangeable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 230,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0  1  2  3  7 11 15]\n",
      "[6]\n"
     ]
    }
   ],
   "source": [
    "Ps = pn.pores(['left', 'back'])\n",
    "print(Ps)\n",
    "Ps = pn.find_neighbor_pores(pores=Ps, mode='xnor')\n",
    "print(Ps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 231,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, pn.Ps, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_left, c='red',\n",
    "                                  markersize=50, marker='*', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_bottom, c='blue',\n",
    "                                  markersize=50, marker='.', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, Ps, c='green',\n",
    "                                  markersize=50, marker='s', ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find Neighboring Throats\n",
    "Neighbor throat queries follow essentially the same logic as the neighboring queries outlined above.  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`mode='or'` finds all throats connected to any of the input pores:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 232,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "Ps = pn.pores(['left', 'back'])\n",
    "Ts = pn.find_neighbor_throats(pores=Ps, mode='or')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 233,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_connections(pn, Ts, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, pn.Ps, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_left, c='red',\n",
    "                                  markersize=50, marker='*', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_bottom, c='blue',\n",
    "                                  markersize=50, marker='.', ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`mode='xnor' finds throats shared by input pores only"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 234,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "Ps = pn.pores(['left', 'back'])\n",
    "Ts = pn.find_neighbor_throats(pores=Ps, mode='xnor')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 235,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_connections(pn, Ts, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, pn.Ps, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_left, c='red',\n",
    "                                  markersize=50, marker='*', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_bottom, c='blue',\n",
    "                                  markersize=50, marker='.', ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`mode=xor` finds throats that are only connected to one input pore"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 236,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "Ps = pn.pores(['left', 'back'])\n",
    "Ts = pn.find_neighbor_throats(pores=Ps, mode='xor')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 237,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_connections(pn, Ts, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, pn.Ps, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_left, c='red',\n",
    "                                  markersize=50, marker='*', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P_bottom, c='blue',\n",
    "                                  markersize=50, marker='.', ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find Connecting Throats\n",
    "\n",
    "Given two sets of pores, it is possible to find which throats connects them using the ``find_connecting_throats``:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 238,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[12 13 14 15]\n"
     ]
    }
   ],
   "source": [
    "P1 = [0, 1, 2, 3]\n",
    "P2 = [4, 5, 6, 7]\n",
    "Ts = pn.find_connecting_throat(P1, P2)\n",
    "print(Ts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 239,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_connections(pn, Ts, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, pn.Ps, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P1, c='red',\n",
    "                                  markersize=50, marker='*', ax=ax)\n",
    "op.visualization.plot_coordinates(pn, P2, c='blue',\n",
    "                                  markersize=50, marker='.', ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This function assumes that `P1` and `P2` are lined up, so that finds the connections between each pore `i`.  If there are no connections, then `nans` are returned (which also means that any valid connections are converted to `float`):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 240,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[nan nan nan 15.]\n"
     ]
    }
   ],
   "source": [
    "P1 = [0, 1, 2, 3]\n",
    "P2 = [7, 7, 7, 7]\n",
    "Ts = pn.find_connecting_throat(P1, P2)\n",
    "print(Ts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Find Connected Pores\n",
    "\n",
    "Given a list of throats, finding which pores are on either end can be done using the `find_connected_pores` method *or* by looking at `pn['throat.conns']` directly."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 241,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 1]\n",
      " [1 2]\n",
      " [2 3]]\n"
     ]
    }
   ],
   "source": [
    "Ps = pn.find_connected_pores(throats=[0, 1, 2])\n",
    "print(Ps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 242,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 1]\n",
      " [1 2]\n",
      " [2 3]]\n"
     ]
    }
   ],
   "source": [
    "Ps = pn['throat.conns'][[0, 1, 2]]\n",
    "print(Ps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is often desired to have a single column of pore indices and to remove duplications.  This can be done with `np.unique`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 243,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3]\n"
     ]
    }
   ],
   "source": [
    "print(np.unique(Ps))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `find_connected_pores` method has a `flatten` argument which does the same thing:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 244,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3]\n"
     ]
    }
   ],
   "source": [
    "Ps = pn.find_connected_pores(throats=[0, 1, 2], flatten=True)\n",
    "print(Ps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Removing Throats\n",
    "\n",
    "Removing throats may be useful for a number of reasons such as making a cubic network more heterogeneous, or to study the effect of blockages on flow.  Throat deletion is actually trivial and requires simply removing the row(s) corresponding to the to-be deleted throats from all throat arrays.  For instance, let's manually delete throats `0` and `3`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 245,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "══════════════════════════════════════════════════════════════════════════════\n",
      "net : <openpnm.network.Cubic at 0x1f7ea245c20>\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Properties                                                   Valid Values\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.coords                                                         6 / 6\n",
      "  2  throat.conns                                                        7 / 7\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Labels                                                 Assigned Locations\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.back                                                               3\n",
      "  2  pore.front                                                              3\n",
      "  3  pore.left                                                               2\n",
      "  4  pore.right                                                              2\n",
      "  5  pore.surface                                                            6\n",
      "  6  throat.surface                                                          7\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n"
     ]
    }
   ],
   "source": [
    "pn = op.network.Cubic(shape=[3, 2, 1])\n",
    "print(pn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see that there are only two arrays which contain throat data, so we need to remove rows 0 and 3 from these. The easiest way to this this actually to \"keep\" the rows we want:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 246,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "══════════════════════════════════════════════════════════════════════════════\n",
      "net : <openpnm.network.Cubic at 0x1f7ea245c20>\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Properties                                                   Valid Values\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.coords                                                         6 / 6\n",
      "  2  throat.conns                                                        5 / 5\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Labels                                                 Assigned Locations\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.back                                                               3\n",
      "  2  pore.front                                                              3\n",
      "  3  pore.left                                                               2\n",
      "  4  pore.right                                                              2\n",
      "  5  pore.surface                                                            6\n",
      "  6  throat.surface                                                          5\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n"
     ]
    }
   ],
   "source": [
    "mask = np.ones(pn.Nt, dtype=bool)\n",
    "mask[[0, 3]] = False\n",
    "pn['throat.conns'] = pn['throat.conns'][mask]\n",
    "pn['throat.surface'] = pn['throat.surface'][mask]\n",
    "print(pn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If any phases have been defined then they need to be handled as well. OpenPNM includes a function to `trim` throats from networks, which handles any complications:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 247,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "══════════════════════════════════════════════════════════════════════════════\n",
      "net : <openpnm.network.Cubic at 0x1f7ea245c20>\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Properties                                                   Valid Values\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.coords                                                         6 / 6\n",
      "  2  throat.conns                                                        3 / 3\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Labels                                                 Assigned Locations\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.all                                                                6\n",
      "  2  pore.back                                                               3\n",
      "  3  pore.front                                                              3\n",
      "  4  pore.left                                                               2\n",
      "  5  pore.right                                                              2\n",
      "  6  pore.surface                                                            6\n",
      "  7  throat.all                                                              3\n",
      "  8  throat.surface                                                          3\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n"
     ]
    }
   ],
   "source": [
    "op.topotools.trim(network=pn, throats=[0, 3])\n",
    "print(pn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Visualizing the network shows that throats are indeed missing, and also that some pores are now isolated which is a problem for numerical computations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 248,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAagAAAEYCAYAAAAJeGK1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8/fFQqAAAACXBIWXMAAAsTAAALEwEAmpwYAAATEUlEQVR4nO3df4zc913n8efL6+xJNWVb4y1n8mMdpDSQQgNhCT97GCGok4qLKhUpKaKiAqw2FHH3B2p0iOYP/gH1DlWIJpZVmagnSITUUHq9tCnSHUQiKtcNStOEXCuTsomJI2/waTnckxav3/fHjJPpen8Z73fm8/U+H9IqO/P9zMxrv3o7r/3OzH4nVYUkSa3ZM+kAkiStx4KSJDXJgpIkNcmCkiQ1yYKSJDVp76QDXK4DBw7UoUOHJh1DkrRDnnrqqVeranbt9b0rqEOHDrGwsDDpGJKkHZJkcb3rfYpPktQkC0qS1CQLSpLUJAtKktQkC0qS1CQLSpLUJAtKktQkC0qS1CQLSpLUJAtKktQkC0qS1KTOCirJiSRnkjy7yZrDSZ5O8lySv+wqiySpf7o8gnoIOLLRxiRvAh4A/n1VvQ34uQ6zSJJ6prOCqqongLObLHkv8GhVvThcf6arLJKk/pnka1BvBd6c5C+SPJXkfRstTHI0yUKShaWlpTFGlCRNyiQLai/wA8C7gHcCv5XkrestrKrjVTVfVfOzs5d8ppUk6So0yQ8sPAW8WlXngHNJngBuBb42wUySpEZM8gjqz4B3JNmb5A3ADwHPTzCPJKkhnR1BJXkYOAwcSHIKuB+4BqCqjlXV80k+DzwDXAA+UVUbviVdkrS7dFZQVXXPNtZ8FPhoVxkkSf3lmSQkSU2yoCRJTbKgJElNsqAkSU2yoCRJTbKgJElNsqAkSU2a5KmOxm51dZXl5WVWVlaYnp5mZmaGqampSceSvolzqj4Yx5zumoI6d+4ci4uLVBVVRRJeeeUV5ubm2Ldv36TjSYBzqn4Y15zuiqf4VldXWVxc5MKFC1QVAFXFhQsXWFxcZHV1dcIJJedU/TDOOd0VBbW8vPzajlyrqlheXh5zIulSzqn6YJxzuiue4ltZWfmmHfrAA2/hwQffMsFE0nr2D78G5ufPsbDg03pqzaVz+od/+HVgUFArKys79ki7oqCmp6dJ8lpJ3XvvGe69d/AJ80k4ePAg+/fv3+wupM6dPXuW06dPr/vbqXOqVqyd0+/93u95bVsSpqend+yxdsVTfDMzMyRZd1sSZmZmxpxIupRzqj4Y55zuioKamppibm6OPXv2vLZjk7Bnzx7m5uZ8C6+a4JyqD8Y5p7viKT6Affv2cfPNN/v3JWqac6o+GJ1TgIMHD/p3UFdqamrK5/DVPOdUfTA6p13N6654ik+S1D8WlCSpSRaUJKlJFpQkqUkWlCSpSRaUJKlJFpQkqUkWlCSpSZ0VVJITSc4keXaLdT+YZDXJe7rKIknqny6PoB4Cjmy2IMkU8LvA4x3mkCT1UGcFVVVPAGe3WPZrwKeAM13lkCT108Reg0pyLfBu4Ng21h5NspBkYWlpqftwkqSJm+SbJD4GfLiqtvwA+6o6XlXzVTU/OzvbfTJJ0sRN8mzm88Ajw88TOQDcmeR8VX16gpkkSY2YWEFV1Y0Xv0/yEPBZy0mSdFFnBZXkYeAwcCDJKeB+4BqAqtrydSdJ0u7WWUFV1T2XsfYXu8ohSeonzyQhSWqSBSVJapIFJUlqkgUlSWqSBSVJapIFJUlqkgUlSWqSBSVJapIFJUlqkgUlSWqSBSVJapIFJUlqkgUlSWqSBSVJapIFJUlqkgUlSWqSBSVJapIFJUlqkgUlSWqSBSVJapIFJUlqkgUlSWqSBSVJapIFJUlqkgUlSWpSZwWV5ESSM0me3WD7zyd5Zvj1ZJJbu8oiSeqfLo+gHgKObLL968BPVNXbgd8GjneYRZLUM3u7uuOqeiLJoU22Pzly8YvAdV1lkST1TyuvQf0S8LmNNiY5mmQhycLS0tIYY0mSJmXiBZXkJxkU1Ic3WlNVx6tqvqrmZ2dnxxdOkjQxnT3Ftx1J3g58Arijqv5xklkkSW2Z2BFUkhuAR4FfqKqvTSqHJKlNnR1BJXkYOAwcSHIKuB+4BqCqjgEfAb4NeCAJwPmqmu8qjySpX7p8F989W2z/ZeCXu3p8SVK/TfxNEpIkrceCkiQ1yYKSJDXJgpIkNcmCkiQ1yYKSJDXJgpIkNcmCkiQ1yYKSJDXJgpIkNcmCkiQ1yYKSJDXJgpIkNcmCkiQ1yYKSJDXJgpIkNcmCkiQ1yYKSJDXJgpIkNcmCkiQ1yYKSJDXJgpIkNcmCkiQ1yYKSJDXJgpIkNamzgkpyIsmZJM9usD1Jfj/JySTPJLmtqyySpP7ZsKCSPJbk0BXc90PAkU223wHcNPw6Cjx4BY8lSbrKbHYE9RDwhSS/meSay73jqnoCOLvJkruAT9bAF4E3JTl4uY8jSbo67d1oQ1X9SZL/DnwEWEjyX4ELI9t/7wof+1rgpZHLp4bXnV67MMlRBkdZ3HDDDVf4sJKkPtjqNah/Ac4B/wZ445qvK5V1rqv1FlbV8aqar6r52dnZHXhoSVLrNjyCSnIE+D3gM8BtVfWNHX7sU8D1I5evA17e4ceQJPXUZkdQvwn8XFXd10E5waD43jd8N98PA8tVdcnTe5Kk3Wmz16DecSV3nORh4DBwIMkp4H7gmuF9HwMeA+4ETgLfAN5/JY8nSbq6bFhQV6qq7tliewG/2tXjS5L6zTNJSJKaZEFJkppkQUmSmmRBSZKaZEFJkppkQUmSmmRBSZKaZEFJkppkQUmSmmRBSZKaZEFJkppkQUmSmmRBSZKaZEFJkppkQUmSmmRBSZKaZEFJkppkQUmSmmRBSZKaZEFJkppkQUmSmmRBSZKaZEFJkppkQUmSmmRBSZKa1GlBJTmS5KtJTia5b53tM0n+W5IvJ3kuyfu7zCNJ6o/OCirJFPBx4A7gFuCeJLesWfarwN9W1a3AYeC/JJnuKpMkqT+6PIK6HThZVS9U1QrwCHDXmjUFvDFJgG8BzgLnO8wkSeqJLgvqWuClkcunhteN+gPgu4GXga8Av15VF9beUZKjSRaSLCwtLXWVV5LUkC4LKutcV2suvxN4GvgO4PuAP0jyrZfcqOp4Vc1X1fzs7OxO55QkNajLgjoFXD9y+ToGR0qj3g88WgMnga8D39VhJklST3RZUF8Cbkpy4/CND3cDn1mz5kXgpwCSfDtwM/BCh5kkST2xt6s7rqrzST4EPA5MASeq6rkkHxhuPwb8NvBQkq8weErww1X1aleZJEn90VlBAVTVY8Bja647NvL9y8DPdJlBktRPnklCktQkC0qS1CQLSpLUJAtKktQkC0qS1CQLSpLUJAtKktQkC0qS1CQLSpLUJAtKktQkC0qS1CQLSpLUJAtKktQkC0qS1CQLSpLUJAtKktQkC0qS1CQLSpLUJAtKktQkC0qS1CQLSpLUJAtKktQkC0qS1CQLSpLUJAtKktSkTgsqyZEkX01yMsl9G6w5nOTpJM8l+csu80iS+mNvV3ecZAr4OPDTwCngS0k+U1V/O7LmTcADwJGqejHJW7rKI0nqly6PoG4HTlbVC1W1AjwC3LVmzXuBR6vqRYCqOtNhHklSj3RZUNcCL41cPjW8btRbgTcn+YskTyV533p3lORokoUkC0tLSx3FlSS1pMuCyjrX1ZrLe4EfAN4FvBP4rSRvveRGVcerar6q5mdnZ3c+qSSpOZ29BsXgiOn6kcvXAS+vs+bVqjoHnEvyBHAr8LUOc0mSeqDLI6gvATcluTHJNHA38Jk1a/4MeEeSvUneAPwQ8HyHmSRJPdHZEVRVnU/yIeBxYAo4UVXPJfnAcPuxqno+yeeBZ4ALwCeq6tmuMkmS+iNVa18Watv8/HwtLCxMOoYkCUjgSmskyVNVNb/2es8kIUlqkgUlSWqSBSVJapIFJUlqkgUlSWqSBSVJapIFJUlqUpenOmrO6uoqy8vLrKysMD09zczMDFNTU5OOJX0T51R9cHFOYT9nz57tZE53TUGdO3eOxcVFqoqqIgmvvPIKc3Nz7Nu3b9LxJMA5VT+Mzins5/Tp053M6a54im91dZXFxUUuXLjAxTNnVBUXLlxgcXGR1dXVCSeUnFP1wzjndFcU1PLyMhud0qmqhoep0mQ5p+qDcc7priiolZWVTXfoysrKmBNJl3JO1Qdr5/SDH3z9g9B3ek53RUFNT0+TrPf5iZCE6enpMSeSLuWcqg/Wzum9975eUDs9p7uioGZmZjb9hz8zMzPmRNKlnFP1wTjndFcU1NTUFHNzc+zZs+e1HZuEPXv2MDc351t41QTnVH0wzjndNW8z37dvHzfffLN/X6KmOafqg3HN6a4pKBg0//79+ycdQ9qUc6o+GMec7oqn+CRJ/WNBSZKaZEFJkppkQUmSmmRBSZKaZEFJkppkQUmSmmRBSZKa1GlBJTmS5KtJTia5b5N1P5hkNcl7uswjSeqPzgoqyRTwceAO4BbgniS3bLDud4HHu8oiSeqfLo+gbgdOVtULVbUCPALctc66XwM+BZxZZ5skaZfqsqCuBV4auXxqeN1rklwLvBs4ttkdJTmaZCHJwtLS0o4HlSS1p8uCWu8DQ9Z+XOjHgA9X1aYfYl9Vx6tqvqrmZ2dndyqfJKlhXZ7N/BRw/cjl64CX16yZBx4ZfqbIAeDOJOer6tMd5pIk9UCXBfUl4KYkNwL/ANwNvHd0QVXdePH7JA8Bn7WcJEnQYUFV1fkkH2Lw7rwp4ERVPZfkA8Ptm77uJEna3Tr9wMKqegx4bM116xZTVf1il1kkSf3imSQkSU2yoCRJTbKgJElNsqAkSU2yoCRJTbKgJElNsqAkSU2yoCRJTbKgJElNsqAkSU1K1dpPwGhbkiVg8Qrv5gDw6g7EGYe+ZDXnzutL1r7khP5k7UtO2Jmsc1V1yWcp9a6gdkKShaqan3SO7ehLVnPuvL5k7UtO6E/WvuSEbrP6FJ8kqUkWlCSpSbu1oI5POsBl6EtWc+68vmTtS07oT9a+5IQOs+7K16AkSe3brUdQkqTGWVCSpCZddQWV5EiSryY5meS+dbYfTrKc5Onh10e2e9sx5/yNkYzPJllNsn+47e+TfGW4baHjnCeSnEny7Abbk+T3hz/HM0luG9k2zv25Vc6fH+Z7JsmTSW4d2Ta2/bnNrK3M6FY5W5nR65P8zyTPJ3kuya+vs6aVOd1O1onP6jZzdj+nVXXVfAFTwN8B3wlMA18Gblmz5jDw2X/NbceZc836nwX+x8jlvwcOjGmf/jvgNuDZDbbfCXwOCPDDwF+Pe39uM+ePAm8efn/HxZzj3p/bzDrxGd1OzoZm9CBw2/D7NwJfW+fffStzup2sE5/VbebsfE6vtiOo24GTVfVCVa0AjwB3jeG2Xee8B3i4oyybqqongLObLLkL+GQNfBF4U5KDjHd/bpmzqp6sqv8zvPhF4LqusmxlG/t0I03t0zUmOaOnq+pvht//X+B54No1y1qZ0y2ztjCr29ynG9mxfXq1FdS1wEsjl0+x/k79kSRfTvK5JG+7zNvuhG0/VpI3AEeAT41cXcAXkjyV5GhHGbdro59lnPvzcv0Sg9+mL2ppf1406RndtpZmNMkh4PuBv16zqbk53STrqInP6hY5O53Tvf+aGzUs61y39n30f8PgvE//nORO4NPATdu87U65nMf6WeCvqmr0N9kfq6qXk7wF+PMk/3v42+4kbPSzjHN/bluSn2Twj/7HR65uaX9CGzN6OZqY0STfwqAk/0NV/dPazevcZGJzukXWi2smPqtb5Ox8Tq+2I6hTwPUjl68DXh5dUFX/VFX/PPz+MeCaJAe2c9tx5hxxN2ueOqmql4f/PQP8KYND6knZ6GcZ5/7cliRvBz4B3FVV/3jx+sb2ZyszejkmPqNJrmHwP9I/qqpH11nSzJxuI2sTs7pVzrHMaZcvtI37i8ER4QvAjbz+4tzb1qz5t7z+B8q3Ay8yaPwtbzvOnMN1MwxeA9g3ct0+4I0j3z8JHOl4vx5i4xf038U3v/j8vy7nZxxjzhuAk8CPrrl+7PtzG1knPqPbydnKjA73zSeBj22ypok53WbWic/qNnN2PqdX1VN8VXU+yYeAxxm8k+REVT2X5APD7ceA9wAfTHIe+H/A3TXYw+vedoI5Ad4NfKGqzo3c/NuBP00Cg0H446r6fBc5AZI8zODdOgeSnALuB64ZyfkYg3dInQS+Abx/s59xgjk/Anwb8MBw352vwRmYx7o/t5l14jO6zZzQwIwCPwb8AvCVJE8Pr/tPDP5H39ScbjNrC7O6nZydz6mnOpIkNelqew1KknSVsKAkSU2yoCRJTbKgJElNsqAkSU2yoKSGDM8i/fW8flbwNw8vz006mzRuFpTUkKp6CXgQ+J3hVb8DHK+qxcmlkibDv4OSGjM8xcxTwAngV4Dvr8FZoaVd5ao6k4R0Naiqf0nyG8DngZ+xnLRb+RSf1KY7gNPA90w6iDQpFpTUmCTfB/w0g5Oa/sfhB+tJu44FJTUkgzOBPsjg83deBD4K/OfJppImw4KS2vIrwItV9efDyw8A35XkJyaYSZoI38UnSWqSR1CSpCZZUJKkJllQkqQmWVCSpCZZUJKkJllQkqQmWVCSpCb9fw+X9nHVkxupAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, pn.Ps, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_connections(pn, ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Removing Pores\n",
    "Removing pores is *almost* as easy as removing throats, with **two significant complications**.  \n",
    "\n",
    "1. When a pore is removed, the values in the `'throat.conns'` array must be updated. If pore 2 is removed, the pore 3 becomes the new pore 2.  This means that any throats which were pointing to pore 3 (i.e. [1, 3]) must now be updated to point to pore 2 instead (i.e. [1, 2]). This can be done manually as shown below, but OpenPNM's `trim` function should be used.\n",
    "2. A throat cannot point to nothing, so when a pore is deleted, all of its neighboring throats must also be deleted.\n",
    "\n",
    "First we'll see how to do this manually, then we'll demonstrate the `trim` function, this time for pores."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first step is to create an array of 0's with 1's in the locations to be trimmed:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 249,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 0 1 0 1 0]\n"
     ]
    }
   ],
   "source": [
    "pn = op.network.Cubic(shape=[3, 2, 1])\n",
    "totrim = np.zeros(pn.Np, dtype=int)\n",
    "totrim[[2, 4]] = 1\n",
    "print(totrim)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now compute the cumulative sum of this array which will then contain values indicating by how much each index should be adjusted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 250,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 0 1 1 2 2]\n"
     ]
    }
   ],
   "source": [
    "offset = np.cumsum(totrim)\n",
    "print(offset)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lastly we create an array that can be used to remap the throat connections:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 251,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 1 2 2 3]\n"
     ]
    }
   ],
   "source": [
    "remap = pn.Ps - offset\n",
    "print(remap)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before we proceed with deleting the pores we must first delete the throats. Luckily this is easy, we just need to identify the neighboring throats, the use `trim`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 252,
   "metadata": {},
   "outputs": [],
   "source": [
    "Ts = pn.find_neighbor_throats(pores=[2, 4])\n",
    "op.topotools.trim(pn, throats=Ts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can delete pores 2 and 4 as we did with throats above:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 253,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "══════════════════════════════════════════════════════════════════════════════\n",
      "net : <openpnm.network.Cubic at 0x1f7ea249db0>\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Properties                                                   Valid Values\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.coords                                                         4 / 4\n",
      "  2  throat.conns                                                        3 / 3\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Labels                                                 Assigned Locations\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.all                                                                4\n",
      "  2  pore.back                                                               3\n",
      "  3  pore.front                                                              1\n",
      "  4  pore.left                                                               2\n",
      "  5  pore.right                                                              1\n",
      "  6  pore.surface                                                            4\n",
      "  7  throat.all                                                              3\n",
      "  8  throat.surface                                                          3\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n"
     ]
    }
   ],
   "source": [
    "mask = np.ones(pn.Np, dtype=bool)\n",
    "mask[[2, 4]] = False\n",
    "for k, v in pn.items():\n",
    "    if k.startswith('pore.'):\n",
    "        pn[k] = v[mask]\n",
    "print(pn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lastly we must remap the throat conns:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 254,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn['throat.conns'] = remap[pn['throat.conns']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 255,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_connections(pn, ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course, the easy way is just to use `trim` directly:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 256,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "pn = op.network.Cubic(shape=[3, 2, 1])\n",
    "op.topotools.trim(network=pn, pores=[2, 4])\n",
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_connections(pn, ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Adding Pores and Throats\n",
    "\n",
    "Adding pores and throats can also be done by hand, but there is one significant complication: when you add a pore or throat, a decision must be made about what values to put into these new locations for all the arrays that already exist. \n",
    "\n",
    "This can be done manually as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 257,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "══════════════════════════════════════════════════════════════════════════════\n",
      "net : <openpnm.network.Cubic at 0x1f7ea32dcc0>\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Properties                                                   Valid Values\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.coords                                                         8 / 8\n",
      "  2  throat.conns                                                        7 / 7\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  #  Labels                                                 Assigned Locations\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n",
      "  1  pore.back                                                               3\n",
      "  2  pore.front                                                              3\n",
      "  3  pore.left                                                               2\n",
      "  4  pore.right                                                              2\n",
      "  5  pore.surface                                                            6\n",
      "  6  throat.surface                                                          7\n",
      "――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――\n"
     ]
    }
   ],
   "source": [
    "pn = op.network.Cubic(shape=[3, 2, 1])\n",
    "new_pores = [[1.5, 2.5, 0.5], [3, 1, 0.5]]\n",
    "coords = np.vstack((pn['pore.coords'], new_pores))\n",
    "pn['pore.coords'] = coords\n",
    "print(pn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We must now extend the length of all the pore arrays as well. We are lucky in this case that only labels are present.  This means we know the shape of of the arrays (i.e. Np-by-1) and we know that `False` is probably the correct value to put into the new locations:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 258,
   "metadata": {},
   "outputs": [],
   "source": [
    "for k in pn.labels():\n",
    "    if k.startswith('pore.'):\n",
    "        pn[k] = np.hstack((pn[k], [False, False]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 259,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_connections(pn, ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's add throats to these new pores:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 260,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_conns = [[1, 6], [4, 7], [5, 7]]\n",
    "conns = np.vstack((pn['throat.conns'], new_conns))\n",
    "pn['throat.conns'] = conns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 261,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_connections(pn, ax=ax);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Obviously, in practice we'd like to use OpenPNM's `extend` method instead:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 262,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn = op.network.Cubic(shape=[3, 2, 1])\n",
    "new_pores = [[1.5, 2.5, 0.5], [3, 1, 0.5]]\n",
    "new_conns = [[1, 6], [4, 7], [5, 7]]\n",
    "op.topotools.extend(network=pn, coords=new_pores)\n",
    "op.topotools.extend(network=pn, conns=new_conns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 263,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "op.visualization.plot_coordinates(pn, c='lightgrey',\n",
    "                                  markersize=50, ax=ax)\n",
    "op.visualization.plot_connections(pn, ax=ax);"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "",
   "title_sidebar": "Contents",
   "toc_cell": true,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "toc-autonumbering": true
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
